﻿using System;
using System.Collections.Generic;
using System.Linq;
using Change = Microsoft.TeamFoundation.VersionControl.Client.Change;
using TfsCommitMonitor.Interfaces;

namespace TfsCommitMonitor.Tfs
{
	internal class Changeset : IEquatable<Changeset>, ICloneable
	{
		private readonly ITfsBusiness _tfsBusiness;

		internal Changeset() : this(new TfsBusiness()) { }
		internal Changeset(ITfsBusiness tfsBusiness)
		{
			_tfsBusiness = tfsBusiness;
		}

		internal Uri CollectionUri { get; set; }
		internal String ProjectPath { get; set; }
		internal Int32 ChangesetId { get; set; }
		internal DateTime CreationDate { get; set; }
		internal String Committor { get; set; }
		internal String Comment { get; set; }
		internal String[] Changes { get; set; }
		internal Boolean Read { get; set; }

		internal Change[] GetTfsChanges()
		{
			return
				_tfsBusiness.GetChangesForChangeset(CollectionUri, ProjectPath, ChangesetId);
		}

		public override bool Equals(Object obj)
		{
			return Equals(obj as Changeset);
		}

		public override Int32 GetHashCode()
		{
			return
				ChangesetId.GetHashCode()
				^
				CreationDate.GetHashCode()
				^
				CollectionUri.GetHashCode()
				^
				Committor.GetHashCode()
				^
				Comment.GetHashCode()
				^
				Changes.GetHashCode()
				^
				ProjectPath.GetHashCode()
				^
				Read.GetHashCode();
		}

		#region IEquatable<Changeset> Members

		public Boolean Equals(Changeset other)
		{
			return
				other != null
				&&
				ChangesetId == other.ChangesetId
				&&
				CreationDate == other.CreationDate
				&&
				((CollectionUri == null && other.CollectionUri == null) || CollectionUri.Equals(other.CollectionUri))
				&&
				Committor == other.Committor
				&&
				Comment == other.Comment
				&&
				((Changes == null && other.Changes == null) || Changes.SequenceEqual(other.Changes))
				&&
				ProjectPath == other.ProjectPath
				&&
				Read == other.Read;
		}

		#endregion

		#region Clone Members

		internal Changeset Clone()
		{
			return
				new Changeset(_tfsBusiness)
				{
					Changes = this.Changes.Select(change => change).ToArray(),
					ChangesetId = this.ChangesetId,
					CollectionUri = new Uri(this.CollectionUri.ToString()),
					Comment = this.Comment,
					Committor = this.Committor,
					CreationDate = this.CreationDate,
					ProjectPath = this.ProjectPath,
					Read = this.Read,
				};
		}

		Object ICloneable.Clone()
		{
			return Clone();
		}

		#endregion	
	}
	internal static class ChangesetHelper
	{
		internal static void MarkAsRead(this IEnumerable<Changeset> changesets)
		{
			foreach (var changeset in changesets)
				changeset.Read = true;
		}
	}
}
